<template>
  <div class="map-marker-filter">
    <div v-if="allController !== false" class="switch-wrap">
      <a-switch v-model:checked="checked" size="small" @change="onSwitchChange" />
      <span @click="() => onSwitchChange()">图层控制</span>
    </div>
    <div v-if="buildController !== false" class="switch-wrap">
      <a-switch v-model:checked="buildChecked" size="small" @change="onBuildSwitchChange" />
      <span @click="() => onBuildSwitchChange()">3D建筑</span>
    </div>
    <!-- 区、街道、社区、网格 -->
    <!-- 账号自身 -->
    <div v-if="areaController !== false" class="switch-wrap">
      <a-switch v-model:checked="areaChecked" size="small" @change="onAreaSwitchChange" />
      <span @click="() => onAreaSwitchChange()">区域范围</span>
    </div>
    <!-- 账号下一级 -->
    <div v-if="communityController !== false" class="switch-wrap">
      <a-switch v-model:checked="communityChecked" size="small" @change="onCommunitySwitchChange" />
      <!-- 根据登录账号等级 -->
      <span @click="() => onCommunitySwitchChange()">{{ levelName }}范围</span>
    </div>
    <!-- 账号再下一级 -->
    <div v-if="gridController !== false" class="switch-wrap">
      <a-switch v-model:checked="gridChecked" size="small" @change="onGridSwitchChange" />
      <span @click="() => onGridSwitchChange()">网格范围</span>
    </div>
    <!-- 一键控制扎点显示、隐藏 -->
    <div v-if="allPointsController !== false" class="switch-wrap">
      <a-switch v-model:checked="allPointsChecked" size="small" @change="onAllPointsSwitchChange" />
      <span @click="() => onAllPointsSwitchChange()">点控制</span>
    </div>
    <antd-menu
      v-model="selectedKeys"
      :menus="dataList"
      :multiple="true"
      :replace-fields="{ key: 'value', title: 'label' }"
      popup-class-name="map-marker-filter-submenu"
      mode="vertical"
      theme="dark"
      @change="onMenuChange"
      @titleClick="titleClick"
    />
  </div>
</template>

<script>
import antdMenu from '@gis/lib/components/antd-menu/index.vue';
import { useUserInfoStore } from '@gis/lib/pinia/userInfo.js';
import { findDeep, getDefaultSelectKeys, getLeafList, getRootParent, turnDataList2DataObj } from './js/filter-utils.js';

export default {
  name: 'map-marker-filter',
  components: { antdMenu },
  props: {
    modelValue: { type: Array, default: () => [] },
    value: { type: Array, default: () => [] },
    dataList: { type: Array, default: () => [] },
    defaultUncheckedKeys: { type: Array, default: () => [] },
    defaultAreaPolygonChecked: { type: Boolean, default: true },
    defaultCommunityPolygonChecked: { type: Boolean, default: true },
    defaultGridPolygonChecked: { type: Boolean, default: false },
    areaController: { type: Boolean, default: true },
    communityController: { type: Boolean, default: true },
    gridController: { type: Boolean, default: true },
    allController: { type: Boolean, default: true },

    buildController: { type: Boolean },
    defaultBuildChecked: { type: Boolean },

    allPointsController: { type: Boolean, default: false }, //所有扎点控制
  },
  data() {
    return {
      allPointsChecked: false, //一键控制所有扎点(默认开or关)
      buildChecked: true, //楼栋3D模型
      checked: true,
      areaChecked: true,
      communityChecked: true,
      gridChecked: true,
      selectedKeys: [],
    };
  },
  watch: {
    dataList: {
      immediate: true,
      handler(list = []) {
        // console.log('dataList ', list);
        this.selectedKeys = getDefaultSelectKeys(list, this.defaultUncheckedKeys);
        this.dataStore = turnDataList2DataObj(list);
        this.onBuildSwitchChange(this.defaultBuildChecked);
        this.onAreaSwitchChange(this.defaultAreaPolygonChecked);
        this.onCommunitySwitchChange(this.defaultCommunityPolygonChecked);
        this.onGridSwitchChange(this.defaultGridPolygonChecked);
        this.output(
          'change',
          Object.keys(this.dataStore)
            .filter((key) => !this.defaultUncheckedKeys.includes(key))
            .map((key) => ({ node: key, leaf: this.dataStore[key] }))
        );
      },
    },
  },
  computed: {
    levelName() {
      const { area_code_level } = useUserInfoStore();
      const area_level = area_code_level('');
      const areaLevelEnum = {
        4: '街道',
        5: '社区',
        6: '网格',
      };
      return areaLevelEnum[area_level];
    },
  },
  methods: {
    getSelectedLeafKeys(parentKey, selected = false) {
      const leaf = this.dataStore[parentKey];
      if (!Array.isArray(leaf)) {
        /* 非数组表示当前 parentKey 对应的菜单是没有子节点的 */
        return selected ? null : [];
      }
      return leaf.filter((key) => this.selectedKeys.indexOf(key) >= 0);
    },

    // 菜单变化
    onMenuChange(e) {
      const root = getRootParent(this.dataList, (o) => o.value === e.key);
      /* isSelected是菜单点击当前状态 */
      const isSelected = this.selectedKeys.includes(e.key);
      const leaf = this.getSelectedLeafKeys(root.value, isSelected);
      this.updateCheckedStatus();
      this.output(
        'filter',
        Object.keys(this.dataStore).map((parentKey) => {
          return {
            node: parentKey,
            leaf: this.getSelectedLeafKeys(parentKey),
          };
        })
      );
    },
    // 包含了下一级菜单的点击事件
    titleClick(e = {}) {
      // 'click'事件会再'select'事件之前执行
      // 导致this.selectedKeys不是最新的
      this.$nextTick(() => {
        const target = findDeep(this.dataList, (o) => o.value === e.value);
        const targetLeaf = getLeafList(target);
        const root = getRootParent(this.dataList, (o) => o.value === e.value);
        const rootKey = root.value;
        /* 只要targetLeaf中有任意一个存在selectedKeys中表示当前按钮处于选中状态 */
        const checked = targetLeaf.some((key) => this.selectedKeys.indexOf(key) >= 0);
        if (checked) {
          this.selectedKeys = this.selectedKeys.filter((key) => targetLeaf.indexOf(key) < 0);
        } else {
          this.selectedKeys = [].concat([], this.selectedKeys, targetLeaf);
        }
        const leaf = this.getSelectedLeafKeys(rootKey, !checked);
        this.updateCheckedStatus();
        // console.log(leaf, this.selectedKeys, '一级菜单点击');
        this.output(
          'filter',
          Object.keys(this.dataStore).map((parentKey) => {
            return {
              node: parentKey,
              leaf: this.getSelectedLeafKeys(parentKey),
            };
          })
        );
      });
    },
    onSwitchChange(checked) {
      if (typeof checked === 'boolean') {
        this.checked = checked;
      } else {
        this.checked = !this.checked;
      }
      if (this.checked) {
        this.selectedKeys = Object.keys(this.dataStore).reduce((res, key) => {
          return [].concat(res, this.dataStore[key]);
        }, []);
      } else {
        this.selectedKeys = [];
      }
      this.onAreaSwitchChange(this.checked);
      this.onBuildSwitchChange(this.checked);
      this.onCommunitySwitchChange(this.checked);
      this.onGridSwitchChange(this.checked);
      this.output(
        'filter',
        Object.keys(this.dataStore).map((parentKey) => ({
          node: parentKey,
          leaf: this.getSelectedLeafKeys(parentKey, checked),
        }))
      );
    },
    // 所有扎点图层控制
    onAllPointsSwitchChange(checked) {
      if (typeof checked === 'boolean') {
        this.allPointsChecked = checked;
      } else {
        this.allPointsChecked = !this.allPointsChecked;
      }
      if (this.allPointsChecked) {
        this.selectedKeys = Object.keys(this.dataStore).reduce((res, key) => {
          return [].concat(res, this.dataStore[key]);
        }, []);
      } else {
        this.selectedKeys = [];
      }
      this.output(
        'filter',
        Object.keys(this.dataStore).map((parentKey) => ({
          node: parentKey,
          leaf: this.getSelectedLeafKeys(parentKey, checked),
        }))
      );
    },
    // 楼栋3D模型 - 切换显示
    onBuildSwitchChange(checked) {
      if (this.buildController === false) {
        this.handleSwitchChange(false, 'buildChecked', 'toggleMapBuilding');
        return;
      }
      if (typeof checked === 'boolean') {
        this.buildChecked = checked;
      } else {
        this.buildChecked = !this.buildChecked;
      }
      this.handleSwitchChange(checked, 'buildChecked', 'toggleMapBuilding');
    },
    onAreaSwitchChange(checked) {
      if (this.areaController === false) {
        this.handleSwitchChange(false, 'areaChecked', 'toggleMapAreaPolygon');
        return;
      }
      if (typeof checked === 'boolean') {
        this.areaChecked = checked;
      } else {
        this.areaChecked = !this.areaChecked;
      }
      // 地图的请求数据，会在这个之后
      setTimeout(() => {
        this.handleSwitchChange(checked, 'areaChecked', 'toggleMapAreaPolygon');
      }, 1000);
    },
    onCommunitySwitchChange(checked) {
      if (this.communityController === false) {
        this.handleSwitchChange(false, 'communityChecked', 'toggleMapCommunityPolygon');
        return;
      }
      if (typeof checked === 'boolean') {
        this.communityChecked = checked;
      } else {
        this.communityChecked = !this.communityChecked;
      }
      this.handleSwitchChange(checked, 'communityChecked', 'toggleMapCommunityPolygon');
    },
    onGridSwitchChange(checked) {
      if (this.gridController === false) {
        this.handleSwitchChange(false, 'gridChecked', 'toggleMapGridPolygon');
        return;
      }
      if (typeof checked === 'boolean') {
        this.gridChecked = checked;
      } else {
        this.gridChecked = !this.gridChecked;
      }
      this.handleSwitchChange(checked, 'gridChecked', 'toggleMapGridPolygon');
    },
    handleSwitchChange(checked, modelKey, emitName) {
      if (typeof checked === 'boolean') {
        this[modelKey] = checked;
      } else {
        this[modelKey] = !this[modelKey];
        this.updateCheckedStatus();
      }
      this.$vbus.$emit(emitName, this[modelKey]);
    },
    updateCheckedStatus() {
      this.checked = !!(
        (this.areaController ? this.areaChecked : false) ||
        (this.communityController ? this.communityChecked : false) ||
        (this.gridController ? this.gridChecked : false) ||
        (this.selectedKeys && this.selectedKeys.length)
      );
    },
    output(event, option = []) {
      /*
       * option: [{
       *   node: parentKey, 实际上是每种marker对应的类名
       *   leaf: null/[], marker的筛选逻辑中leaf为非数组时不会进行筛选并且显示所有扎点,为[]时会过滤掉所有扎点
       * }]
       * */
      this.$nextTick(() => {
        this.$emit('update:modelValue', this.selectedKeys.slice(0));
        this.$emit('input', this.selectedKeys.slice(0));
        this.$emit(event, option);
      });
    },
  },
};
</script>

<style lang="less">
.antMenuStyles {
  background: rgba(10, 37, 55, 0.7);
  border: none;

  .ant-menu-item,
  .ant-menu-submenu {
    color: #efefef;
  }

  .ant-menu-item,
  .ant-menu-submenu {
    display: flex;
    align-items: center;
    height: 26px;
    line-height: 1;
    margin: 5px 0;
    transition: filter ease 0.3s, color ease 0.1s;

    //-webkit-filter: grayscale(100%);
    //filter: grayscale(100%);
    //color: #a0a0a0;

    .ant-menu-submenu-title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      height: 100%;
      margin: 0;
      line-height: 1;
      color: inherit;
      .ant-menu-title-content {
        display: flex;
        align-items: center;
        color: inherit;
      }
    }

    &.ant-menu-item-selected,
    &.ant-menu-submenu-selected {
      background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(66, 255, 255, 0.3) 50%, rgba(0, 0, 0, 0) 100%);
      -webkit-filter: grayscale(0%);
      filter: grayscale(0%);
      color: #efefef;
    }

    &:hover,
    &.ant-menu-item-selected:hover,
    &.ant-menu-submenu-selected:hover {
      background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(66, 255, 255, 0.3) 50%, rgba(0, 0, 0, 0) 100%);
    }
  }

  //.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item:not(.ant-menu-item-selected):hover {
  //  background: none;
  //}
  //.ant-menu-dark .ant-menu-item:hover:not(.ant-menu-item-selected):not(.ant-menu-submenu-selected) {
  //  color: #fff !important;
  //}
}

.map-marker-filter,
.map-marker-filter-submenu {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  .menu-icon {
    width: 18px;
    height: 18px;
    margin-right: 5px;
  }
}

.map-marker-filter {
  .ant-menu {
    padding: 5px 0;
    .antMenuStyles();
  }
  .ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-item:not(.ant-menu-item-selected):hover {
    background: none;
  }
  .ant-menu-dark .ant-menu-item:hover:not(.ant-menu-item-selected):not(.ant-menu-submenu-selected),
  .ant-menu-dark .ant-menu-submenu-title:hover:not(.ant-menu-item-selected):not(.ant-menu-submenu-selected) {
    color: #ffffff;
  }
  .switch-wrap {
    display: flex;
    align-items: center;
    padding: 10px 16px 0;
    background: rgba(10, 37, 55, 0.7);
    color: #efefef;
    & > span {
      margin-left: 3px;
      cursor: pointer;
    }
  }
}
.map-marker-filter-submenu {
  &.ant-menu-submenu.ant-menu-submenu-popup {
    background: none;
    .ant-menu {
      max-height: 50vh;
      overflow: hidden auto;
      .antMenuStyles();
    }
  }
}
</style>
